package org.apaydin;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class CalendarUtils {
    private static final long MILLISECS_PER_DAY = 24 * 60 * 60 * 1000;

    public static Calendar addSeconds(Calendar orig, int seconds) {
        return add(orig, Calendar.SECOND, seconds);
    }

    public static Calendar addDays(Calendar orig, int amount) {
        return add(orig, Calendar.DAY_OF_YEAR, amount);
    }

    public static Calendar add(Calendar orig, int field, int amount) {
        Calendar newCalendar = (Calendar) orig.clone();
        newCalendar.add(field, amount);
        return newCalendar;
    }

    public static Calendar clearTimeFields(Calendar cal) {
        cal.set(Calendar.HOUR_OF_DAY, cal.getActualMinimum(Calendar.HOUR_OF_DAY));
        cal.clear(Calendar.MINUTE);
        cal.clear(Calendar.SECOND);
        cal.clear(Calendar.MILLISECOND);
        return cal;
    }

    public static Calendar toCalendar(Date date) {
        return toCalendar(date.getTime());
    }

    public static Calendar toCalendar(long millis) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(millis);
        return calendar;
    }

    public static long dayDiff(Calendar begin, Calendar end) {
        long endL = end.getTimeInMillis() + end.getTimeZone().getOffset(end.getTimeInMillis());
        long startL = begin.getTimeInMillis() + begin.getTimeZone().getOffset(begin.getTimeInMillis());
        return (endL - startL) / MILLISECS_PER_DAY;
    }


    public static String toString(Calendar date, String pattern) {
        return new SimpleDateFormat(pattern).format(date.getTime());
    }

    public static String toString(Calendar date) {
        return toString(date, "dd/MM/yyyy");
    }

    public static int getYear(Date date) {
        return getYear(toCalendar(date));
    }

    public static int getYear(Calendar date) {
        return date.get(Calendar.YEAR);
    }

    public static Calendar toCalendar(String val, String pattern) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        try {
            return toCalendar(sdf.parse(val));
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }

    public static Date dayBeginTime(Date date) {
        return clearTimeFields(toCalendar(date)).getTime();
    }

    public static Date dayEndTime(Date date) {
        Calendar cal = toCalendar(date);

        cal.set(Calendar.HOUR_OF_DAY, cal.getActualMaximum(Calendar.HOUR_OF_DAY));
        cal.set(Calendar.MINUTE, cal.getActualMaximum(Calendar.MINUTE));
        cal.set(Calendar.SECOND, cal.getActualMaximum(Calendar.SECOND));
        cal.set(Calendar.MILLISECOND, cal.getActualMaximum(Calendar.MILLISECOND));

        return cal.getTime();
    }

    public static boolean sameDay(Calendar c1, Calendar c2) {
        return c1.get(Calendar.YEAR) == c2.get(Calendar.YEAR) && c1.get(Calendar.DAY_OF_YEAR) == c2.get(Calendar.DAY_OF_YEAR);
    }

    public static boolean sameHour(Calendar c1, Calendar c2) {
        return c1.get(Calendar.YEAR) == c2.get(Calendar.YEAR) && c1.get(Calendar.MONTH) == c2.get(Calendar.MONTH) &&
                c1.get(Calendar.DAY_OF_MONTH) == c2.get(Calendar.DAY_OF_MONTH) &&
                c1.get(Calendar.HOUR_OF_DAY) == c2.get(Calendar.HOUR_OF_DAY);
    }

    public static int secondsBetween(Calendar c1, Calendar c2) {
        return (int) (Math.abs(c1.getTimeInMillis() - c2.getTimeInMillis()) / 1000.0);
    }
}
